import {
  ArgumentMetadata,
  HttpException,
  HttpStatus,
  Injectable,
  Logger,
  PipeTransform,
} from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform {
  // value 是当前处理的参数， metadata是其元数据
  async transform(value: any, metadata: ArgumentMetadata) {
    const { metatype } = metadata;
    // metatype不存在，或者校验失败，直接返回数据
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    // 将对象转换为Class来验证
    const object = plainToClass(metatype, value);
    const errors = await validate(object);
    Logger.log(errors, 'validation.pipe处理');
    if (errors.length > 0) {
      // 获取第一个错误并且直接返回
      const msg = Object.values(errors[0].constraints)[0];
      // 抛出异常
      throw new HttpException({ message: msg }, HttpStatus.OK);
    }

    return value;
  }
  private toValidate(metatype: any): boolean {
    const types = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
